package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.entity.SetmealDto;
import com.itheima.reggie.exception.CustomException;
import com.itheima.reggie.mapper.SetmealMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper,Setmeal> implements SetmealService {

    //注入套餐关联相关菜品服务
    @Autowired
    private SetmealDishService setmealDishService;

    //注入菜品分类服务
    @Autowired
    private CategoryService categoryService;

    @Override
    public void saveWithDish(SetmealDto setmealDto) {
        //创建套餐对象 将传入的数据copy到该对象中进行保存 (忽略“setmealDishes”字段)
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDto,setmeal,"setmealDishes");

        //将套餐对象添加到数据表中
        if (this.save(setmeal)) {
            log.info("套餐数据添加成功!{}",setmeal);
        }

        //获取到dto中的setmealDishes数据集合
        List<SetmealDish> dishList = setmealDto.getSetmealDishes();
        //使用stream流操作遍历每一条数据 对该stream流对象进行map映射操作 -> 设置套餐id

        List<SetmealDish> list = dishList.stream().map((item) -> {
                    //设置套餐id 遍历出每个菜品批量新增菜品
                    item.setSetmealId(setmeal.getId());
                    return item;
                }
        ).collect(Collectors.toList());

        setmealDishService.saveBatch(list);
    }

    @Override
    public void removeWithDish(List<Long> ids) {
        log.info("ids{}",ids);
        //查询该批次套餐中是否存在售卖中的套餐 如果存在则不允许删除
        for (Long id : ids) {
            LambdaQueryWrapper<Setmeal> qw = new LambdaQueryWrapper<>();
            qw.eq(ids.size() != 0,Setmeal::getStatus,1).eq(id != null && id != 0,Setmeal::getId,id);
            int count = this.count(qw);
            if (count > 0) throw new CustomException("抱歉！删除套餐中存在正在售卖的套餐...");

        }

        //程序能够走到这里说明套餐状态为或都为0(停售状态)
        //删除套餐数据
        if (this.removeByIds(ids)) {
            log.info("ids[{}]套餐删除成功!",ids);
        }
        //本类上已经添加了事务@Trancational注解
        ArrayList<Long> longs = new ArrayList<>();
        for (int i = 0; i < ids.size(); i++) {
            LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ids.size() != 0,SetmealDish::getSetmealId,ids.get(i));
            List<SetmealDish> list = setmealDishService.list(queryWrapper);
            for (SetmealDish setmealDish : list) {
                longs.add(setmealDish.getId());
            }
        }
        //删除套餐关联菜品数据
        setmealDishService.removeByIds(longs);
    }

    @Override
    public Page<SetmealDto> findPage(Integer page, Integer pageSize, String name) {
        //创建Page<Setmeal> 对象 注入 page pageSize name 属性值进行查询 (data)
        Page<Setmeal> setmealPage = new Page<>(page,pageSize);
        //按照更新时间进行降序
        LambdaQueryWrapper<Setmeal> qw = new LambdaQueryWrapper<>();
        qw.like(name != null,Setmeal::getName,name);
        qw.orderByDesc(Setmeal::getUpdateTime);

        this.page(setmealPage, qw);

        //创建Page<SetmealDto> page分页查询类
        Page<SetmealDto> dtoPage = new Page<>();
        //将基本分页信息 如:当前页码 总数据条数 每页显示条数  copy转移 但是需要忽略返回的Setmeal套餐数据list
        BeanUtils.copyProperties(setmealPage,dtoPage,"records");

        //构造用于设置进入 dtoPage.setRecords() 的list集合变量
        List<SetmealDto> setmealDtoList = new ArrayList<>();


        //循环遍历setmealPage对象的返回数据组

        List<Setmeal> setmeals = setmealPage.getRecords();

        for (Setmeal setmeal : setmeals) {
            //创建一个SetmealDto类型的对象
            SetmealDto dto = new SetmealDto();
            //将setmeal对象中的属性data Copy 进入dto对象
            BeanUtils.copyProperties(setmeal,dto);
            //创建Lambda分类查询选择器
            // LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
            // wrapper.eq(Category::getId,setmeal.getCategoryId());
            //通过调用Category服务查询出套餐分类对象
            Category category = categoryService.getById(setmeal.getCategoryId());
            //将获取到的分类对象的categoryName属性值set到dto对象中
            dto.setCategoryName(category.getName());
            //添加到List<SetmealDto>中
            setmealDtoList.add(dto);
        }

        //设置Page<SetmealDto>的records属性
        dtoPage.setRecords(setmealDtoList);
        return dtoPage;
    }


    @Override
    public void modifyPackageData(SetmealDto setmealDto) {
        //套餐增强实体类
        System.out.println("setmealDto = " + setmealDto);
        //更新基本数据
        this.updateById(setmealDto);  //setmealDto继承了setmeal 所以 可以作为参数传入
        //操作菜品套餐关系表.删除所有绑定了套餐该套餐的菜品 (根据dto中套餐id = 关系表中setmeal_id)
        LambdaQueryWrapper<SetmealDish> qw = new LambdaQueryWrapper<>();
        qw.eq(SetmealDish::getSetmealId,setmealDto.getId());
        setmealDishService.remove(qw);
        //获取到dto中存有的所有菜品信息
        List<SetmealDish> dishList = setmealDto.getSetmealDishes();
        List<SetmealDish> dishes = dishList.stream().map((item) -> {
            //遍历其中的每一条数据  给菜品中的setmealId进行赋值 (当前套餐id)
            item.setSetmealId(setmealDto.getId());
            return item;
        }).collect(Collectors.toList());
        //调用关系表服务层进行数据新增
        setmealDishService.saveBatch(dishes);
    }

    @Override
    public void modifyState(int state, Long[] ids) {
        LambdaUpdateWrapper<Setmeal> uw = new LambdaUpdateWrapper<>();
        uw.set(Setmeal::getStatus,state).in(Setmeal::getId,ids);
        this.update(uw);
    }

    @Override
    public SetmealDto getSetmealData(Long id) {

        Setmeal setmeal = this.getById(id);
        SetmealDto dto = new SetmealDto();
        BeanUtils.copyProperties(setmeal,dto);
        dto.setCategoryName(categoryService.getById(setmeal.getCategoryId()).getName());
        LambdaQueryWrapper<SetmealDish> qw = new LambdaQueryWrapper<>();
        qw.eq(setmeal.getId() != null ,SetmealDish::getSetmealId,id);
        List<SetmealDish> list = setmealDishService.list(qw);
        dto.setSetmealDishes(list);
        return dto;
    }
}
